#include "include/ucwebimagejpeg2jpeg.h"


ucwebImageJpeg2Jpeg::ucwebImageJpeg2Jpeg()
{

}

ucwebImageJpeg2Jpeg::ucwebImageJpeg2Jpeg(const char* filename, int quality, float percentage_resize, const char* outfilename)
  :filename(filename), quality_image(quality), percentage_resize(percentage_resize), blob(NULL), image(NULL), decom_jpeg_done(0), output(NULL)
{
  //sprintf(outfile, "outputjpeg%d", file_no);
  sprintf(outfile, "../changed/%s", outfilename);
}



ucwebImageJpeg2Jpeg::~ucwebImageJpeg2Jpeg()
{
  if (blob) {
    delete blob;
  }

  if (image) {
    delete image;
  }

}

int ucwebImageJpeg2Jpeg::DecompressByJpeglib(bool resize=false)
{
  FILE *in_file = fopen(filename.c_str(), "rb");
  if (NULL == in_file) {
    fprintf(stderr, "Error! Failed open the input picture file!\n");
    //cout << filename << endl;
    return -1;
  }
  int ok = -1;
  struct jpeg_decompress_struct dinfo;

  JSAMPROW buffer[1];
  struct jpeg_error_mgr jerr;

  dinfo.err = jpeg_std_error(&jerr);

  jpeg_create_decompress(&dinfo);
  jpeg_stdio_src(&dinfo, in_file);
  jpeg_read_header(&dinfo, TRUE);

  dinfo.out_color_space = JCS_RGB;
  dinfo.do_fancy_upsampling = TRUE;
  if (resize) {
    dinfo.scale_num = 1;
    dinfo.scale_denom = 2;
  }
  //jpeg_calc_output_dimensions(&dinfo);
  jpeg_start_decompress(&dinfo);

  output = new jpeg_image_info_byjpegc;

  if (NULL == output) {
    fprintf(stderr, "Error! Cannot new memory for output infomation at %d in %s\n", __LINE__, __FILE__);
    goto End;
  }

  output->width = dinfo.output_width;

  output->height = dinfo.output_height;
  output->stride = dinfo.output_width * dinfo.output_components * sizeof(*(output->rgb));
  output->rgb = (uint8_t*)malloc(output->stride * output->height);
  if (output->rgb == NULL) {  
    goto End;
  }
  buffer[0] = (JSAMPLE*)(output->rgb);

  while (dinfo.output_scanline < dinfo.output_height) {
    if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) {
      goto End;
    }

    buffer[0] += output->stride;
  }

  jpeg_finish_decompress(&dinfo);
  jpeg_destroy_decompress(&dinfo);

  ok = 0;
  goto End;

End:
  fclose(in_file);
  return ok;
}

int ucwebImageJpeg2Jpeg::DecomJpegResizeJpegComJpeg()
{
  /*
  if (decom_jpeg_done) {
    fprintf(stderr, "DecompressByJpeglib has been done !\n");
    return 0;
  }
  */
  DecompressByJpeglib(true);
  int ok = -1;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);
  JDIMENSION num_scanlines;
  unsigned int scanline = 0; 
  
  FILE* out_file = fopen(outfile, "wb");
  if (NULL == out_file) {
    fprintf(stderr, "Error! Faile open the output image file! at %d in %s. \n", __LINE__, __FILE__);
    goto End;
  }
 
  //src_mgr->input_file = in_file;
  //(*src_mgr->start_input)(&cinfo, src_mgr);
  
  jpeg_stdio_dest(&cinfo, out_file);

  cinfo.image_width = int(output->width /* percentage_resize*/);
  cinfo.image_height = int(output->height /* percentage_resize*/);
  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;
  //jpeg_default_colorspace(&cinfo);
  jpeg_set_defaults(&cinfo);
  jpeg_set_quality(&cinfo, quality_image, TRUE);

  jpeg_start_compress(&cinfo, TRUE);

  JSAMPROW row_pointer[1];
  while (scanline < /*output->heigh*/ output->height) {
    row_pointer[0] = &(output->rgb[/*cinfo.next_scanline*/ scanline * output->stride]);
    jpeg_write_scanlines(&cinfo, row_pointer, 1);
    scanline++;
  }

  //(*src_mgr->finish_imput) (&cinfo, src_mgr);
  jpeg_finish_compress(&cinfo);
  jpeg_destroy_compress(&cinfo);

  fclose(out_file);
  ok = 0;
  goto End;

End:
  return ok;
}


int ucwebImageJpeg2Jpeg::ResizeByGm(bool quality=false)
{
  int ok = -1;
  if (NULL == image) {
    fprintf(stderr, "Error! The image is NULL at %d in %s\n", __LINE__, __FILE__);
    return ok;
  }
  
  int resize_w = (int)(image->columns() * percentage_resize);
  int resize_h = (int)(image->rows() * percentage_resize);
  Magick::Geometry geometry(resize_w, resize_h);
  geometry.aspect(true);
  image->scale(geometry);
  if (quality) {
    image->quality(quality_image);
  }
  ok = 0;
  goto End;

End:
 return ok;
}


int ucwebImageJpeg2Jpeg::DecompressByGm()
{
  try {
    // Read a file into image object
    image = new Magick::Image(filename);
    // Write the image to a file
    return 0;
  }catch( Exception &error_ )
  {
    cout << "Caught exception: " << error_.what() << endl;
    return -1;
  }
}

int ucwebImageJpeg2Jpeg::CompressByGm()
{
  
}

int ucwebImageJpeg2Jpeg::DecomGmResizeGmComGm()
{
  int ok  = -1;

  if (-1 == DecompressByGm()) {
    fprintf(stderr, "Error! Failed decompress the image file! at %d in %s.\n", __LINE__, __FILE__);
    return -1;
  }

  if (-1 == ResizeByGm(true)) {
    fprintf(stderr, "Error! Failed resizing the image file! at %d in %s.\n", __LINE__, __FILE__);
    return -1;
  }
  string outfilename(outfile);
  image->write(outfilename);
  
  ok = 0;
  goto End;

End:
  return ok;
}
